home *** CD-ROM | disk | FTP | other *** search
/ CD ROM Paradise Collection 4 / CD ROM Paradise Collection 4 1995 Nov.iso / edit / thesrc20.zip / the.c < prev    next >
C/C++ Source or Header  |  1995-01-26  |  34KB  |  906 lines

  1. /***********************************************************************/
  2. /* THE.C - The Hessling Editor                                         */
  3. /***********************************************************************/
  4. /*
  5.  * THE - The Hessling Editor. A text editor similar to VM/CMS xedit.
  6.  * Copyright (C) 1991-1995 Mark Hessling
  7.  *
  8.  * This program is free software; you can redistribute it and/or
  9.  * modify it under the terms of the GNU General Public License as
  10.  * published by the Free Software Foundation; either version 2 of
  11.  * the License, or any later version.
  12.  *
  13.  * This program is distributed in the hope that it will be useful,
  14.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  15.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  16.  * General Public License for more details.
  17.  *
  18.  * You should have received a copy of the GNU General Public License
  19.  * along with this program; if not, write to:
  20.  *
  21.  *    The Free Software Foundation, Inc.
  22.  *    675 Mass Ave,
  23.  *    Cambridge, MA 02139 USA.
  24.  *
  25.  *
  26.  * If you make modifications to this software that you feel increases
  27.  * it usefulness for the rest of the community, please email the
  28.  * changes, enhancements, bug fixes as well as any and all ideas to me.
  29.  * This software is going to be maintained and enhanced as deemed
  30.  * necessary by the community.
  31.  *
  32.  * Mark Hessling                     email: M.Hessling@gu.edu.au
  33.  * 36 David Road                     Phone: +61 7 849 7731
  34.  * Holland Park                      Fax:   +61 7 875 5314
  35.  * QLD 4121
  36.  * Australia
  37.  */
  38.  
  39. /*
  40. $Id: the.c 2.0 1995/01/26 16:32:06 MH Release MH $
  41. */
  42.  
  43. #include <stdio.h>
  44.  
  45. #define MAIN 1
  46. #include "the.h"
  47. #include "proto.h"
  48. #include <signal.h>
  49.  
  50. #if defined(DOS) || defined(OS2)
  51. #  if !defined(EMX) && !defined(GO32)
  52. #    include <direct.h>
  53. #  endif
  54. #endif
  55.  
  56. /*--------------------------- global data -----------------------------*/
  57.  WINDOW *foot=NULL,*error_window=NULL,*divider=NULL;
  58.  VIEW_DETAILS *vd_current=(VIEW_DETAILS *)NULL;
  59.  VIEW_DETAILS *vd_first=(VIEW_DETAILS *)NULL;
  60.  VIEW_DETAILS *vd_mark=(VIEW_DETAILS *)NULL;
  61.  CHARTYPE number_of_views = 0;                      /* number of views */
  62.  CHARTYPE number_of_files = 0;                      /* number of files */
  63.  CHARTYPE display_screens = 1;                    /* number of screens */
  64.  CHARTYPE current_screen = 0;
  65.  SCREEN_DETAILS screen[MAX_SCREENS];            /* 2 screen structures */
  66.  bool rexx_support;                          /* initially REXX support */
  67.  bool horizontal=TRUE;
  68.  short save_coord_x[VIEW_WINDOWS];
  69.  short save_coord_y[VIEW_WINDOWS];
  70.  
  71.  LINE *next_line=NULL,*curr_line=NULL;
  72.  LINE *first_file_name=NULL,*current_file_name=NULL;
  73.  bool error_on_screen=FALSE;
  74.  bool colour_support=TRUE;         /* indicates if colour is supported */
  75.  bool initial=TRUE;
  76.  CHARTYPE *rec=NULL;
  77.  LENGTHTYPE rec_len = 0;                              /* length of rec */
  78.  CHARTYPE *cmd_rec=NULL;
  79.  unsigned short cmd_rec_len = 0;                  /* length of cmd_rec */
  80.  CHARTYPE *pre_rec=NULL;
  81.  unsigned short pre_rec_len = 0;                  /* length of cmd_rec */
  82.  bool focus_changed = FALSE;    /* indicates if focus line has changed */
  83.  bool current_changed = FALSE;/* indicates if current line has changed */
  84.  bool in_profile=FALSE;             /* indicates if processing profile */
  85.  bool execute_profile=TRUE;/* indicates if we are to process a profile */
  86.  bool in_macro=FALSE;            /* indicates if processing REXX macro */
  87.  bool file_read=FALSE;           /* indicates if we have read the file */
  88.  bool curses_started=FALSE;         /* indicates if curses has started */
  89.  bool readonly=FALSE;     /* indicates if running THE in readonly mode */
  90.  
  91.  CHARTYPE *the_version = (CHARTYPE *)"2.0";
  92.  CHARTYPE *the_copyright = (CHARTYPE *)"Copyright 1991-1995 Mark Hessling";
  93.  CHARTYPE term_name[20];  /* $TERM value */
  94. #if defined(UNIX)
  95.  CHARTYPE user_home_dir[MAX_FILE_NAME+1];
  96. #   define THE_PROFILE_FILE ".therc"
  97. #else
  98. #   define THE_PROFILE_FILE "PROFILE.THE"
  99. #endif
  100.  CHARTYPE *helpfilename = (CHARTYPE *)"THE.HLP";
  101.  CHARTYPE *tempfilename = (CHARTYPE *)"THE.$$$";
  102.  CHARTYPE *rexxoutname = (CHARTYPE *)"REXX.$$$";
  103.  CHARTYPE rexx_pathname[MAX_FILE_NAME+1];
  104.  CHARTYPE rexx_filename[10];
  105. #ifdef VMS
  106.  CHARTYPE *dirfilename = (CHARTYPE *)"DIR.THE";
  107. #else
  108.  CHARTYPE *dirfilename = (CHARTYPE *)"DIR.DIR";
  109. #endif
  110.  CHARTYPE macro_suffix[12] = ".the";   /* default extension for macros */
  111.  CHARTYPE dir_pathname[MAX_FILE_NAME+1];
  112.  CHARTYPE dir_filename[10];
  113.  CHARTYPE curr_path[MAX_FILE_NAME+1];
  114.  CHARTYPE sp_path[MAX_FILE_NAME+1];
  115.  CHARTYPE sp_fname[MAX_FILE_NAME+1];
  116.  CHARTYPE dir_path[MAX_FILE_NAME+1];        /* for dir and ls commands */
  117.  
  118.  CHARTYPE the_home_dir[MAX_FILE_NAME+1];
  119.  CHARTYPE the_macro_path[MAX_FILE_NAME+1];        /* for macro command */
  120.  CHARTYPE the_help_file[MAX_FILE_NAME+1];
  121.  CHARTYPE the_profile_file[MAX_FILE_NAME+1];
  122.  
  123.  CHARTYPE *prf_arg=(CHARTYPE *)NULL;
  124.  bool profile_specified=FALSE;
  125.  
  126.  CHARTYPE tabkey_insert='C';
  127.  CHARTYPE tabkey_overwrite='T';
  128.  unsigned short file_start = 36;
  129.  CHARTYPE *last_target=NULL;
  130.  
  131. #if defined(UNIX) || defined(OS2)
  132.  CHARTYPE *spooler_name=NULL;
  133. #endif
  134.  
  135.  CHARTYPE file_disposition=0;
  136.  
  137.  struct stat stat_buf;
  138.  
  139.  short lastrc=0;
  140.  short compatible=COMPAT_THE;
  141.  short prefix_width=PREFIX_WIDTH;
  142.  
  143. #define DEFAULT_LINES 24
  144. #define DEFAULT_COLS  80
  145. /*---------------------------------------------------------------------*/
  146. /* Following are for getopt function(s).                               */
  147. /*---------------------------------------------------------------------*/
  148. extern char *optarg;
  149. extern int optind;
  150. /*---------------------------------------------------------------------*/
  151. /* Following are for original cursor position for EXTRACT /CURSOR/     */
  152. /*---------------------------------------------------------------------*/
  153.  LINETYPE original_screen_line = (-1L);
  154.  LINETYPE original_screen_column = (-1L);
  155.  LINETYPE original_file_line = (-1L);
  156.  LINETYPE original_file_column = (-1L);
  157.  
  158. #ifdef XCURSES
  159.  char *XCursesProgramName = "the";
  160. #endif
  161. /***********************************************************************/
  162. #ifdef MSWIN
  163. int Themain(argc,argv)
  164. int argc;
  165. char *argv[];
  166. #else
  167. #ifdef PROTO
  168. int main(int argc, char *argv[])
  169. #else
  170. int main(argc,argv)
  171. short argc;
  172. char *argv[];
  173. #endif
  174. #endif
  175. /***********************************************************************/
  176. {
  177. /*-------------------------- external data ----------------------------*/
  178.  extern ROWTYPE STATUSLINEx;
  179.  extern DEFINE *first_define;
  180.  extern bool CLEARSCREENx;
  181.  extern bool INSERTMODEx;
  182.  extern LINE *first_prefix_synonym;
  183.  
  184. #ifdef MSWIN
  185.  extern void efree();
  186.  extern char far *emalloc(unsigned long);
  187.  extern char far *erealloc(void far *,unsigned long);
  188.  extern char far *ecalloc();
  189. #endif
  190. /*--------------------------- local data ------------------------------*/
  191.  register short i=0;
  192.  CHARTYPE *prf=(CHARTYPE *)NULL;
  193.  short c=0;
  194.  bool trap_signals=TRUE;
  195.  bool pause_for_errors=FALSE;
  196.  short rc=RC_OK;
  197. /*--------------------------- processing ------------------------------*/
  198. #ifdef __EMX__
  199.  _wildcard(&argc,&argv);
  200. #endif
  201.  
  202. #ifdef TRACE
  203.  trace_initialise();
  204.  trace_function("the.c:     main");
  205. #endif
  206. /*---------------------------------------------------------------------*/
  207. /* Ensure that CURRENT_VIEW is NULL before starting. This is to ensure */
  208. /* that any errors generated before CURRENT_VIEW is assigned are       */
  209. /* handled gracefully.                                                 */
  210. /*---------------------------------------------------------------------*/
  211.  CURRENT_VIEW = (VIEW_DETAILS *)NULL;
  212. /*---------------------------------------------------------------------*/
  213. /* Set up our memory management calls. This is where you can specify a */
  214. /* debugging memory manager.                                           */
  215. /*---------------------------------------------------------------------*/
  216. #ifdef MSWIN
  217.  the_malloc  = emalloc;
  218.  the_calloc  = ecalloc;
  219.  the_free    = efree;
  220.  the_realloc = erealloc;
  221.  Win31Startup();
  222. #else
  223.  the_malloc  = malloc;
  224.  the_calloc  = calloc;
  225.  the_free    = free;
  226.  the_realloc = realloc;
  227. #endif
  228. /*---------------------------------------------------------------------*/
  229. /* Set up flag to indicate that we are not interactive...yet.          */
  230. /*---------------------------------------------------------------------*/
  231.  in_profile = TRUE;
  232.  execute_profile = TRUE;
  233.  in_macro = FALSE;
  234. /*---------------------------------------------------------------------*/
  235. /* Initialise the printer spooler.                                     */
  236. /*---------------------------------------------------------------------*/
  237. #if defined(UNIX) || defined(OS2)
  238.  if ((spooler_name = (CHARTYPE *)(*the_malloc)(4*sizeof(CHARTYPE))) == NULL)
  239.    {
  240.     display_error(30,(CHARTYPE *)"",FALSE);
  241.     exit_clean(1);
  242.    }
  243. #  ifdef UNIX
  244.  strcpy(spooler_name,(CHARTYPE *)"lpr");
  245. #  else
  246.  strcpy(spooler_name,(CHARTYPE *)"LPT1");
  247. #  endif
  248. #endif
  249. /*---------------------------------------------------------------------*/
  250. /* Get all environment variables here. Some may be overridden by       */
  251. /* command-line switches. (future possibility)                         */
  252. /*---------------------------------------------------------------------*/
  253. #if defined(UNIX)
  254.  if (getenv("HOME") != NULL)
  255.     strcpy(user_home_dir,getenv("HOME"));
  256.  else
  257.     strcpy(user_home_dir,"./");
  258.  if (*(user_home_dir+strlen(user_home_dir)-1) != ISLASH)
  259.     strcat(user_home_dir,ISTR_SLASH);
  260.  if (getenv("TERM") != NULL)
  261.     strcpy(term_name,getenv("TERM"));
  262.  else
  263.     strcpy(term_name,"default");
  264. #endif
  265. #if defined(DOS)
  266.  strcpy(term_name,"DOS");
  267. #endif
  268. #if defined(OS2)
  269.  strcpy(term_name,"OS2");
  270. #endif
  271. /*---------------------------------------------------------------------*/
  272. /* Get THE_HOME_DIR first (as all other paths rely on this value)      */
  273. /*---------------------------------------------------------------------*/
  274.  if (getenv("THE_HOME_DIR") != NULL)
  275.    {
  276.     strcpy(the_home_dir,getenv("THE_HOME_DIR"));
  277.     (void *)strtrans(the_home_dir,OSLASH,ISLASH);
  278.     if ((the_home_dir[strlen(the_home_dir)-1]) != ISLASH)
  279.        strcat(the_home_dir,ISTR_SLASH);
  280.    }
  281.  else
  282.    {
  283. #if defined(UNIX)
  284.     strcpy(the_home_dir,THE_HOME_DIRECTORY);
  285. #else
  286.     strcpy(the_home_dir,(CHARTYPE *)argv[0]);
  287.     (void *)strtrans(the_home_dir,OSLASH,ISLASH);
  288.     i = strzreveq(the_home_dir,ISLASH);
  289.     if (i != (-1))
  290.        the_home_dir[i+1] = '\0';
  291.     else
  292.        the_home_dir[0] = '\0';
  293. #endif
  294.    }
  295. /*---------------------------------------------------------------------*/
  296. /* Get THE_MACRO_PATH environment variable. If not set set up default  */
  297. /* to be THE_HOME_DIR followed by the current directory.               */
  298. /*---------------------------------------------------------------------*/
  299.  if (getenv("THE_MACRO_PATH") != NULL)
  300.     strcpy(the_macro_path,getenv("THE_MACRO_PATH"));
  301.  else
  302.    {
  303.     strcpy(the_macro_path,the_home_dir);
  304. #if defined(UNIX)
  305.     strcat(the_macro_path,":.");
  306. #else
  307.     strcat(the_macro_path,";.");
  308. #endif
  309.    }
  310.  (void *)strtrans(the_macro_path,OSLASH,ISLASH);
  311. #ifdef VMS
  312.  strcpy(the_macro_path,"");
  313. #endif
  314. /*---------------------------------------------------------------------*/
  315. /* Set up help file name.                                              */
  316. /*---------------------------------------------------------------------*/
  317.  if (getenv("THE_HELP_FILE") != NULL)
  318.     strcpy(the_help_file,getenv("THE_HELP_FILE"));
  319.  else
  320.    {
  321.     strcpy(the_help_file,the_home_dir);
  322.     strcat(the_help_file,term_name);
  323.     strcat(the_help_file,".hlp");
  324.    }
  325.  (void *)strtrans(the_help_file,OSLASH,ISLASH);
  326. /*---------------------------------------------------------------------*/
  327. /* Set up profile file name.                                           */
  328. /*---------------------------------------------------------------------*/
  329.  if (getenv("THE_PROFILE_FILE") != NULL)
  330.     strcpy(the_profile_file,getenv("THE_PROFILE_FILE"));
  331.  else
  332.    {
  333. #if defined(UNIX)
  334.     strcpy(the_profile_file,user_home_dir);
  335. #else
  336.     strcpy(the_profile_file,the_home_dir);
  337. #endif
  338.     strcat(the_profile_file,THE_PROFILE_FILE);
  339.    }
  340.  (void *)strtrans(the_profile_file,OSLASH,ISLASH);
  341. /*---------------------------------------------------------------------*/
  342. /* Process the command line arguments.                                 */
  343. /*---------------------------------------------------------------------*/
  344.  while ((c = getopt(argc,argv,"smnrp:w:a:h?")) != EOF)
  345.    switch((char)c)
  346.      {
  347.       case 's':        /* don't trap signals */
  348.                trap_signals = FALSE;
  349.                break;
  350.       case 'm':        /* force into MONO */
  351.                colour_support = FALSE;
  352.                break;
  353.       case 'n':        /* do not execute any profile file */
  354.                execute_profile = FALSE;
  355.                break;
  356.       case 'r':        /* run in readonly mode */
  357.                readonly = TRUE;
  358.                break;
  359.       case 'p':        /* profile file name */
  360.                if ((prf = (CHARTYPE *)(*the_malloc)((strlen(optarg)+1)*sizeof(CHARTYPE))) == NULL)
  361.                  {
  362.                   display_error(30,(CHARTYPE *)"",FALSE);
  363.                   exit_clean(1);
  364.                  }
  365.                strcpy(prf,optarg);
  366.                break;
  367.       case 'a':        /* profile arguments */
  368.                if ((prf_arg = (CHARTYPE *)(*the_malloc)((strlen(optarg)+1)*sizeof(CHARTYPE))) == NULL)
  369.                  {
  370.                   display_error(30,(CHARTYPE *)"",FALSE);
  371.                   exit_clean(1);
  372.                  }
  373.                strcpy(prf_arg,optarg);
  374.                break;
  375.       case 'w':        /* width of line */
  376.                max_line_length = (unsigned short)atoi(optarg);
  377.                if (max_line_length < 10)
  378.                  {
  379.                   display_error(5,(CHARTYPE *)"width MUST be >= 10",FALSE);
  380.                   exit_clean(1);
  381.                  }
  382.                break;
  383.       case 'h':
  384.       case '?':
  385.                display_info((CHARTYPE *)argv[0]);
  386.                exit_clean(0);
  387.                break;
  388.       default:
  389.                break;
  390.      }
  391.  
  392.  if (optind<argc)
  393.    {
  394.     while(optind<argc)
  395.       {
  396.        if ((current_file_name = add_line(first_file_name,
  397.                                          current_file_name,
  398.                                          strtrans((CHARTYPE *)argv[optind],OSLASH,ISLASH),
  399.                                          strlen(argv[optind]),0)) == NULL)
  400.            {
  401.             display_error(30,(CHARTYPE *)"",FALSE);
  402.             exit_clean(1);
  403.            }
  404.        if (first_file_name == NULL)
  405.           first_file_name = current_file_name;
  406.        optind++;
  407.       }
  408.    }
  409.  else
  410.    {
  411.     if ((current_file_name = add_line(first_file_name,
  412.                                       current_file_name,
  413.                                       CURRENT_DIR,
  414.                                       strlen(CURRENT_DIR),0)) == NULL)
  415.         {
  416.          display_error(30,(CHARTYPE *)"",FALSE);
  417.          exit_clean(1);
  418.         }
  419.     if (first_file_name == NULL)
  420.        first_file_name = current_file_name;
  421.    }
  422. /*---------------------------------------------------------------------*/
  423. /* Override any default paths,filenames etc if supplied on command line*/
  424. /*---------------------------------------------------------------------*/
  425.  if (prf != NULL)
  426.    {
  427.     strcpy(the_profile_file,prf);
  428.     (void *)strtrans(the_profile_file,OSLASH,ISLASH);
  429.     profile_specified = TRUE;
  430.    }
  431. /*---------------------------------------------------------------------*/
  432. /* Allocate some memory to last_target and set it to a blank value.    */
  433. /*---------------------------------------------------------------------*/
  434.  if ((last_target = (CHARTYPE *)(*the_malloc)(80*sizeof(CHARTYPE))) == NULL)
  435.     exit_clean(1);
  436.  strcpy(last_target,"");
  437. /*---------------------------------------------------------------------*/
  438. /* Allocate some memory to rec.                                        */
  439. /*---------------------------------------------------------------------*/
  440.  if ((rec = (CHARTYPE *)(*the_malloc)((max_line_length+1)*sizeof(CHARTYPE))) == NULL)
  441.     exit_clean(1);
  442. /*---------------------------------------------------------------------*/
  443. /* Allocate some memory for temporary space...                         */
  444. /*---------------------------------------------------------------------*/
  445.  if (allocate_temp_space(max_line_length,TEMP_PARAM) != RC_OK)
  446.     exit_clean(1);
  447.  if (allocate_temp_space(max_line_length,TEMP_TMP_CMD) != RC_OK)
  448.     exit_clean(1);
  449.  if (allocate_temp_space(max_line_length,TEMP_TEMP_CMD) != RC_OK)
  450.     exit_clean(1);
  451. /* if (allocate_temp_space(max_line_length,TEMP_MACRO) != RC_OK)
  452.     exit_clean(1);*/
  453. /*---------------------------------------------------------------------*/
  454. /* Allocate memory to pre_rec and set it to blanks.                    */
  455. /*---------------------------------------------------------------------*/
  456.  if ((pre_rec = (CHARTYPE *)(*the_malloc)((PREFIX_WIDTH+1)*sizeof(CHARTYPE))) == NULL)
  457.     exit_clean(1);
  458.  memset(pre_rec,' ',PREFIX_WIDTH+1);
  459.  pre_rec_len = 0;
  460. /*---------------------------------------------------------------------*/
  461. /* Determine the current working directory.                            */
  462. /* Do this before any other file setting up so that we don't change the*/
  463. /* current directory from the default.                                 */
  464. /*---------------------------------------------------------------------*/
  465. #if defined(EMX)
  466.  _getcwd2(curr_path,MAX_FILE_NAME);
  467. #else
  468.  getcwd(curr_path,MAX_FILE_NAME);
  469. #endif
  470. /*---------------------------------------------------------------------*/
  471. /* Set up filename for directory temporary file (DIR.DIR).             */
  472. /* Set up filename for REXX capture file (REXX.$$$).                   */
  473. /*---------------------------------------------------------------------*/
  474. #ifdef UNIX
  475.  strcpy(dir_pathname,user_home_dir);
  476. #endif
  477. #if defined(DOS) || defined(OS2)
  478.  strcpy(dir_pathname,ISTR_SLASH);
  479. #endif
  480. #ifdef VMS
  481.  strcpy(dir_pathname,"");
  482. #endif
  483.  
  484.  strcpy(rexx_pathname,dir_pathname);
  485.  strcat(dir_pathname,dirfilename);
  486.  if (splitpath(dir_pathname) != RC_OK)
  487.     exit_clean(1);
  488.  strcpy(dir_pathname,sp_path);
  489.  strcpy(dir_filename,sp_fname);
  490.  
  491.  strcat(rexx_pathname,rexxoutname);
  492.  if (splitpath(rexx_pathname) != RC_OK)
  493.     exit_clean(1);
  494.  strcpy(rexx_pathname,sp_path);
  495.  strcpy(rexx_filename,sp_fname);
  496. /*---------------------------------------------------------------------*/
  497. /* Trap signals to exit gracefully, unless user has specified they not */
  498. /* be trapped.                                                         */
  499. /*---------------------------------------------------------------------*/
  500.  if (trap_signals)
  501.     init_signals();
  502. /*---------------------------------------------------------------------*/
  503. /* Set SCREEN values up...                                             */
  504. /*---------------------------------------------------------------------*/
  505.  for (i=0;i<VIEW_WINDOWS;i++)
  506.      CURRENT_SCREEN.win[i] = (WINDOW *)NULL;
  507. /*---------------------------------------------------------------------*/
  508. /* Set up global defaults.                                             */
  509. /*---------------------------------------------------------------------*/
  510.  set_global_defaults();
  511. /*---------------------------------------------------------------------*/
  512. /* Initialise command array to empty strings.                          */
  513. /*---------------------------------------------------------------------*/
  514.  init_command();
  515. /*---------------------------------------------------------------------*/
  516. /* Initialise rexx support. If no REXX available, set flag...          */
  517. /*---------------------------------------------------------------------*/
  518. #ifndef MSWIN
  519.  rexx_support = TRUE;
  520.  if (initialise_rexx() != RC_OK)
  521.     rexx_support = FALSE;
  522. #endif
  523. /*---------------------------------------------------------------------*/
  524. /* Set up variables and values dependent on LINES and COLS now with    */
  525. /* default settings that will be altered after initscr().              */
  526. /*---------------------------------------------------------------------*/
  527.  LINES = DEFAULT_LINES;
  528.  COLS = DEFAULT_COLS;
  529.  screen[0].sl = screen[1].sl = NULL;
  530.  set_defaults();
  531. /*---------------------------------------------------------------------*/
  532. /* Read each file into memory and apply the profile file to each of the*/
  533. /* files.                                                              */
  534. /*---------------------------------------------------------------------*/
  535.  current_file_name = first_file_name;
  536.  while(current_file_name != NULL)
  537.    {
  538.    if ((rc = get_file((CHARTYPE *)current_file_name->line)) != RC_OK)
  539.      {
  540.       if (rc == RC_DISK_FULL)
  541.          display_error(57,(CHARTYPE *)"...probably",FALSE);
  542.       exit_clean(2);
  543.      }
  544.    pre_process_line(CURRENT_VIEW,0L);
  545.    if (execute_profile)
  546.      {
  547.       (void)get_profile(prf_arg);
  548.       if (error_on_screen)
  549.         {
  550.          pause_for_errors = TRUE;
  551.          error_on_screen = FALSE;
  552.         }
  553. #ifdef MSWIN
  554.       (void)get_user_profile();
  555.       if (error_on_screen)
  556.         {
  557.          pause_for_errors = TRUE;
  558.          error_on_screen = FALSE;
  559.         }
  560. #endif
  561.      }
  562.    current_file_name = current_file_name->next;
  563.    }
  564.  if (number_of_files == 0)
  565.     exit_clean(0);
  566.  lll_free(first_file_name);
  567.  CURRENT_VIEW = CURRENT_SCREEN.screen_view = vd_first;
  568.  pre_process_line(CURRENT_VIEW,CURRENT_VIEW->focus_line);
  569. /* CURRENT_VIEW->current_window = WINDOW_COMMAND;*/
  570.  
  571. /*---------------------------------------------------------------------*/
  572. /* If we have had an error in the profile file we need to pause so the */
  573. /* user sees the messages. This pause should only occur if the number  */
  574. /* of files > 0. ie the profile file does not contain a 'file' or 'quit*/
  575. /* command.                                                            */
  576. /*---------------------------------------------------------------------*/
  577.  if (pause_for_errors && number_of_files != 0)
  578.    {
  579.     fprintf(stderr,"\n%s","Hit RETURN to continue...");
  580.     fflush(stderr);
  581.     (void)getchar();
  582.     error_on_screen = FALSE;
  583.    }
  584. /*---------------------------------------------------------------------*/
  585. /* Start up curses. This allows profile commands to be processed before*/
  586. /* curses starts.                                                      */
  587. /*---------------------------------------------------------------------*/
  588.  initscr();
  589.  curses_started = TRUE;
  590. /*---------------------------------------------------------------------*/
  591. /* Determine if colour support available.                              */
  592. /*---------------------------------------------------------------------*/
  593.  if (colour_support) /* if default setting not overridden on command line */
  594.    {
  595.     colour_support = FALSE;
  596. #ifdef A_COLOR
  597.     if (has_colors())
  598.       {
  599.        start_color();
  600.        colour_support = TRUE;
  601.        init_colour_pairs();
  602.       }
  603. #endif
  604.    }
  605. /*---------------------------------------------------------------------*/
  606. /* Set various terminal characteristics...                             */
  607. /*---------------------------------------------------------------------*/
  608. #if !defined(VMS)
  609.  cbreak();
  610. #endif
  611. #if !defined(MINIX)
  612.  raw();
  613. #endif
  614. #if defined(USE_EXTCURSES)
  615.  extended(FALSE);
  616. #endif
  617. #if defined(DOS) || defined(OS2)
  618.  raw_output(TRUE);
  619. #endif
  620.  nonl();
  621.  noecho();
  622. #if !defined(NO_KEYPAD)
  623.  keypad(stdscr,TRUE);
  624. #endif
  625. #if defined(USE_NOTIMEOUT)
  626.  notimeout(stdscr,TRUE);
  627. #endif
  628. /*---------------------------------------------------------------------*/
  629. /* We are now finished with profile commands.                          */
  630. /*---------------------------------------------------------------------*/
  631.  in_profile = FALSE;
  632. /*---------------------------------------------------------------------*/
  633. /* Set up variables and values dependent on LINES and COLS now with    */
  634. /* values set by initscr().                                            */
  635. /*---------------------------------------------------------------------*/
  636.  set_defaults();
  637. /*---------------------------------------------------------------------*/
  638. /* Call insertmode command to set default mode to whatever the current */
  639. /* setting is. If set in profile, could be anything.                   */
  640. /* Run AFTER initscr() as it uses curs_set().                          */
  641. /*---------------------------------------------------------------------*/
  642.  Insertmode(INSERTMODEx ? "ON" : "OFF");
  643. /*---------------------------------------------------------------------*/
  644. /* For each file being edited, set up the curses windows for each of  */
  645. /* them.                                                               */
  646. /*---------------------------------------------------------------------*/
  647.  CURRENT_VIEW = CURRENT_SCREEN.screen_view = vd_first;
  648.  
  649.  for (i=0;i<display_screens;i++)
  650.     if (set_up_windows(i) != RC_OK)
  651.        exit_clean(1);
  652.  
  653.  CURRENT_VIEW = CURRENT_SCREEN.screen_view = vd_first;
  654.  pre_process_line(CURRENT_VIEW,CURRENT_VIEW->focus_line);
  655. /*---------------------------------------------------------------------*/
  656. /* Create the statusline window...                                     */
  657. /*---------------------------------------------------------------------*/
  658.  if (create_statusline_window() != RC_OK)
  659.    {
  660.     display_error(0,(CHARTYPE *)"creating status line window",FALSE);
  661.     exit_clean(2);
  662.    }
  663. /*---------------------------------------------------------------------*/
  664. /* This is where it all happens.                                       */
  665. /*---------------------------------------------------------------------*/
  666.  editor();
  667. /*---------------------------------------------------------------------*/
  668. /* Finalise rexx support...                                            */
  669. /*---------------------------------------------------------------------*/
  670. #ifndef MSWIN
  671.  finalise_rexx();
  672. #endif
  673. /*---------------------------------------------------------------------*/
  674. /* Get rid of any temporary directory file or REXX capture file.       */
  675. /*---------------------------------------------------------------------*/
  676.  strcpy(sp_path,dir_pathname);
  677.  strcat(sp_path,dir_filename);
  678.  remove_file(sp_path);
  679.  
  680.  strcpy(sp_path,rexx_pathname);
  681.  strcat(sp_path,rexx_filename);
  682.  remove_file(sp_path);
  683. /*---------------------------------------------------------------------*/
  684. /* Free up the dynamically allocated memory.                           */
  685. /*---------------------------------------------------------------------*/
  686.  if (first_define != NULL)
  687.     first_define = dll_free(first_define);
  688.  if (first_prefix_synonym != NULL)
  689.     first_prefix_synonym = lll_free(first_prefix_synonym);
  690.  (*the_free)(last_target);
  691.  (*the_free)(rec);
  692.  (*the_free)(cmd_rec);
  693.  if (screen[0].sl != NULL)
  694.     (*the_free)(screen[0].sl);
  695.  if (screen[1].sl != NULL)
  696.     (*the_free)(screen[1].sl);
  697. /*---------------------------------------------------------------------*/
  698. /* Free memory for temp_params and tmp_cmd                             */
  699. /*---------------------------------------------------------------------*/
  700.  free_temp_space(TEMP_PARAM);
  701.  free_temp_space(TEMP_MACRO);
  702.  free_temp_space(TEMP_TEMP_CMD);
  703.  free_temp_space(TEMP_TMP_CMD);
  704.  
  705.  if (prf != NULL)
  706.     (*the_free)(prf);
  707.  if (prf_arg != NULL)
  708.     (*the_free)(prf_arg);
  709.  free_recovery_list();
  710.  
  711. #if defined(UNIX) || defined(OS2)
  712.  (*the_free)(spooler_name);
  713. #endif
  714.  
  715.  if (divider != (WINDOW *)NULL)
  716.    {
  717.     delwin(divider);
  718.     divider = (WINDOW *)NULL;
  719.    }
  720.  if (error_window != (WINDOW *)NULL)
  721.    {
  722.     delwin(error_window);
  723.     error_window = (WINDOW *)NULL;
  724.    }
  725. /*---------------------------------------------------------------------*/
  726. /* If the user wants a clearscreen done before exiting, do it...       */
  727. /*---------------------------------------------------------------------*/
  728.  if (CLEARSCREENx)
  729.    {
  730.     wclear(stdscr);
  731.     move(0,0);
  732.     attrset(A_NORMAL);
  733.     refresh();
  734.    }
  735.  else
  736. /*---------------------------------------------------------------------*/
  737. /* ...otherwise, get the cursor to the bottom line.                    */
  738. /*---------------------------------------------------------------------*/
  739.    {
  740.     if (foot != (WINDOW *)NULL)
  741.       {
  742.        wattrset(foot,A_NORMAL);
  743.        mvwaddstr(foot,0,0,"THE - END");
  744.        wrefresh(foot);
  745.       }
  746.    }
  747.  if (foot != (WINDOW *)NULL)
  748.    {
  749.     delwin(foot);
  750.     foot = (WINDOW *)NULL;
  751.    }
  752. #ifdef MSWIN
  753.  Win31Cleanup();
  754.  return(0);
  755. #endif
  756.  exit_clean(0);
  757. }
  758. /***********************************************************************/
  759. #ifdef PROTO
  760. void init_signals(void)
  761. #else
  762. void init_signals()
  763. #endif
  764. /***********************************************************************/
  765. {
  766. /*--------------------------- local data ------------------------------*/
  767. /*--------------------------- processing ------------------------------*/
  768. #ifdef TRACE
  769.  trace_function("the.c:     init_signals");
  770. #endif
  771. #ifdef UNIX
  772.  signal(SIGQUIT,handle_signal);
  773.  signal(SIGHUP,handle_signal);
  774.  signal(SIGABRT,handle_signal);
  775.  signal(SIGFPE,handle_signal);
  776.  signal(SIGSEGV,handle_signal);
  777.  signal(SIGINT,handle_signal);
  778.  signal(SIGTERM,handle_signal);
  779. #if defined(SIGBUS)
  780.  signal(SIGBUS,handle_signal);
  781. #endif
  782. #endif
  783. #ifdef TRACE
  784.  trace_return();
  785. #endif
  786.  return;
  787. }
  788. /***********************************************************************/
  789. #ifdef PROTO
  790. void init_colour_pairs(void)
  791. #else
  792. void init_colour_pairs()
  793. #endif
  794. /***********************************************************************/
  795. {
  796. /*--------------------------- local data ------------------------------*/
  797.  register int fg=0,bg=0;
  798. /*--------------------------- processing ------------------------------*/
  799. #ifdef TRACE
  800.  trace_function("the.c:     init_colour_pairs");
  801. #endif
  802.  
  803. #ifdef A_COLOR
  804.  for (fg=0;fg<COLORS;fg++)
  805.    {
  806.     for (bg=0;bg<COLORS;bg++)
  807.       {
  808.        if (ATTR2PAIR(fg,bg) <= COLOR_PAIRS)
  809.           init_pair(ATTR2PAIR(fg,bg),fg,bg);
  810.       }
  811.    }
  812. #endif
  813.  
  814. #ifdef TRACE
  815.  trace_return();
  816. #endif
  817.  return;
  818. }
  819. #ifdef UNIX
  820. /***********************************************************************/
  821. #ifdef PROTO
  822. void handle_signal(int err)
  823. #else
  824. void handle_signal(err)
  825. int err;
  826. #endif
  827. /***********************************************************************/
  828. {
  829. /*--------------------------- local data ------------------------------*/
  830. /*--------------------------- processing ------------------------------*/
  831. #ifdef TRACE
  832.  trace_function("the.c:     handle_signal");
  833. #endif
  834.  if (curses_started)
  835.     endwin();
  836.  fprintf(stderr,"\nTHE terminated with signal: %d\n\n",err);
  837.  exit_clean(2);
  838. }
  839. #endif
  840. /***********************************************************************/
  841. #ifdef PROTO
  842. void display_info(CHARTYPE *argv0)
  843. #else
  844. void display_info(argv0)
  845. CHARTYPE *argv0;
  846. #endif
  847. /***********************************************************************/
  848. {
  849. /*--------------------------- local data ------------------------------*/
  850. /*--------------------------- processing ------------------------------*/
  851.  
  852.  fprintf(stderr,"\nTHE %s %s. All rights reserved.\n",the_version,the_copyright);
  853.  fprintf(stderr,"THE is distributed under the terms of the GNU General Public License \n");
  854.  fprintf(stderr,"and comes with NO WARRANTY. See the file COPYING for details.\n");
  855.  fprintf(stderr,"\nUsage:\n\n%s [-h?nms] [-p profile] [-a profile_arg] [-w width] [[dir] [file [...]]]\n",argv0);
  856.  fprintf(stderr,"\nwhere:\n\n");
  857.  fprintf(stderr,"-h,-?                  show this message\n");
  858.  fprintf(stderr,"-n                     do not execute a profile file\n");
  859.  fprintf(stderr,"-m                     force display into mono\n");
  860.  fprintf(stderr,"-r                     run THE in read-only mode\n");
  861.  fprintf(stderr,"-s                     turn off signal trapping (Unix only)\n");
  862.  fprintf(stderr,"-p profile             filename of profile file\n");
  863.  fprintf(stderr,"-a profile_arg         argument(s) to profile file (only with REXX)\n");
  864.  fprintf(stderr,"-w width               maximum width of line (default 2048)\n");
  865.  fprintf(stderr,"[dir [file [...]]]     file(s) and/or directory to be edited\n\n");
  866.  fflush(stderr);
  867.  return;
  868. }
  869. /***********************************************************************/
  870. #ifdef PROTO
  871. void exit_clean(short err_num)
  872. #else
  873. void exit_clean(err_num)
  874. short err_num;
  875. #endif
  876. /***********************************************************************/
  877. {
  878. /*-------------------------- external data ----------------------------*/
  879. extern bool CLEARSCREENx;
  880. extern bool INSERTMODEx;
  881. /*--------------------------- local data ------------------------------*/
  882. /*--------------------------- processing ------------------------------*/
  883. #ifdef TRACE
  884.  trace_function("the.c:     exit_clean");
  885. #endif
  886.  
  887.  if (curses_started)
  888.    {
  889.     INSERTMODEx=FALSE;
  890.     draw_cursor(TRUE);
  891. #ifdef BSD
  892.     nl();
  893.     echo();
  894. #endif
  895.     endwin();
  896.    }
  897.  if (!CLEARSCREENx)
  898.     printf("\n");
  899.  if (file_exists(tempfilename))
  900.     remove_file(tempfilename);
  901. #ifdef TRACE
  902.  trace_return();
  903. #endif
  904.  exit(err_num);
  905. }
  906.